package com.ics.atable.chat.util;

import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.Map;
import java.util.HashMap;
import java.time.ZoneId;
import java.time.ZonedDateTime;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

/**
 * 时间语义解析工具：
 * 从自然语言中提取年份与季度（table_year / task_quarter）。
 *
 * 规则示例：
 * - 本年第三季度 / 本年第3季 => year = 当前年, quarter = 3
 * - 今年Q2 => year = 当前年, quarter = 2
 * - 上年一季度 / 去年第一季度 => year = 当前年-1, quarter = 1
 * - 2024年第四季度 => year = 2024, quarter = 4
 * - 本年第1季度的上一季度 => year = 当前年-1, quarter = 4（跨年）
 * - 本季 => year = 当前年, quarter = 当前季度
 * - 仅有“本年/今年/本年度/全年”等且未指定季度：quarter = -1, 且 aggregateYear = true（表示全年合计 Q1..Q4）
 */
public class TimeParseUtil {

    /** 映射中文数字到阿拉伯数字 */
    private static final Map<Character, Integer> CN_DIGIT = new HashMap<>();
    static {
        CN_DIGIT.put('一', 1);
        CN_DIGIT.put('二', 2);
        CN_DIGIT.put('三', 3);
        CN_DIGIT.put('四', 4);
        CN_DIGIT.put('五', 5);
        CN_DIGIT.put('六', 6);
        CN_DIGIT.put('七', 7);
        CN_DIGIT.put('八', 8);
        CN_DIGIT.put('九', 9);
        CN_DIGIT.put('十', 10);
        CN_DIGIT.put('〇', 0);
        CN_DIGIT.put('零', 0);
        CN_DIGIT.put('0', 0);
        CN_DIGIT.put('1', 1);
        CN_DIGIT.put('2', 2);
        CN_DIGIT.put('3', 3);
        CN_DIGIT.put('4', 4);
        CN_DIGIT.put('5', 5);
        CN_DIGIT.put('6', 6);
        CN_DIGIT.put('7', 7);
        CN_DIGIT.put('8', 8);
        CN_DIGIT.put('9', 9);
    }

    private static final Pattern YEAR_EXPLICIT = Pattern.compile("(?<!\\d)(20\\d{2})(?:年)?");
    private static final Pattern QUARTER_CN = Pattern.compile("([一二三四1234])季度");
    private static final Pattern QUARTER_SEASON = Pattern.compile("第([一二三四1234])季(?!度)");
    private static final Pattern QUARTER_Q = Pattern.compile("[Qq]([1-4])");
    private static final Pattern PREV_QUARTER = Pattern.compile("(上一季度|上季度|前一季度|的上一季度|的上季度|的前一季度|的上一季|的上季|的前一季)");
    private static final Pattern WHOLE_YEAR = Pattern.compile("(本年|今年|本年度|全年)");
    private static final Pattern CURRENT_QUARTER = Pattern.compile("(本季度|当前季度|这季度|这季)");

    /**
     * 从文本提取年份和季度，默认使用当前年份和季度。
     * @param text 输入文本
     * @return YearQuarter 结果对象；若未识别季度，quarter = -1
     */
    public static YearQuarter extractYearQuarter(String text) {
        int currentYear = getCurrentYear();
        int currentQuarter = getCurrentQuarter();
        return extractYearQuarter(text, currentYear, currentQuarter);
    }

    /**
     * 从文本提取年份和季度。
     * @param text 输入文本
     * @param currentYear 当前年份（用于解析“本年/今年/上年/去年”）
     * @return YearQuarter 结果对象；若未识别季度，quarter = -1
     */
    public static YearQuarter extractYearQuarter(String text, int currentYear) {
        int currentQuarter = getCurrentQuarter();
        return extractYearQuarter(text, currentYear, currentQuarter);
    }

    /**
     * 从文本提取年份和季度。
     * @param text 输入文本
     * @param currentYear 当前年份（用于解析"本年/今年/上年/去年"）
     * @param currentQuarter 当前季度（用于解析"本季"和"上一季度"）
     * @return YearQuarter 结果对象；若未识别季度，quarter = -1
     */
    public static YearQuarter extractYearQuarter(String text, int currentYear, int currentQuarter) {
        if (text == null) {
            return new YearQuarter(currentYear, -1, false);
        }
        String norm = normalize(text);
        
        // 解析年份和季度
        int year = detectYear(norm, currentYear);
        int quarter = detectQuarter(norm, currentQuarter);
        
        // 检查是否包含"上一季度"语义
        boolean prevQuarter = PREV_QUARTER.matcher(norm).find();

        // 处理"上一季度"语义
        if (prevQuarter) {
            if (quarter > 0) {
                // 如果已经解析出具体的季度，则计算上一季度
                // 但如果这个季度是从"本季度"检测出来的，应该使用系统当前季度
                int quarterToUse = quarter;
                Matcher currentQuarterMatcher = CURRENT_QUARTER.matcher(norm);
                if (currentQuarterMatcher.find()) {
                    quarterToUse = getCurrentQuarter();
                }
                YearQuarter prev = previousQuarter(year, quarterToUse);
                year = prev.getTableYear();
                quarter = prev.getTaskQuarter();
            } else {
                // 未给出具体季度，则参考传入的当前季度参数
                // 但如果文本包含"本季度"或"当前季度"，应该使用系统当前季度而不是传入的currentQuarter
                int quarterToUse = currentQuarter;
                Matcher currentQuarterMatcher = CURRENT_QUARTER.matcher(norm);
                if (currentQuarterMatcher.find()) {
                    quarterToUse = getCurrentQuarter();
                }
                YearQuarter prev = previousQuarter(year, quarterToUse);
                year = prev.getTableYear();
                quarter = prev.getTaskQuarter();
            }
        }

        // 是否是"本年/全年"汇总（当未指定具体季度时）
        boolean aggregate = false;
        if (quarter <= 0 && WHOLE_YEAR.matcher(norm).find()) {
            aggregate = true; // 表示 1-4 季合计
        }

        return new YearQuarter(year, quarter, aggregate);
    }

    private static String normalize(String s) {
        // 全角/半角归一化
        StringBuilder sb = new StringBuilder();
        for (char c : s.toCharArray()) {
            if (c >= '０' && c <= '９') { // 全角数字
                sb.append((char) (c - '０' + '0'));
            } else if (c == '年' || c == '月' || c == '日' || c == '季' || c == '当' || c == '前' || c == '上' || c == '本' || c == '今' || c == '去' || c == '昨' || c == '度' || c == '第' || c == 'q' || c == 'Q') {
                sb.append(c);
            } else {
                sb.append(c);
            }
        }
        return sb.toString().replaceAll("\\s+", "");
    }

    private static int detectYear(String norm, int currentYear) {
        // 显式年份优先：2024年、2025
        Matcher yearMatcher = YEAR_EXPLICIT.matcher(norm);
        if (yearMatcher.find()) {
            try { return Integer.parseInt(yearMatcher.group(1)); } catch (Exception ignored) {}
        }
        
        // 处理复合表达：今年前一年 -> 当前年-1
        if (norm.contains("今年前一年") || norm.contains("本年前一年")) {
            return getCurrentYear() - 1;
        }
        
        // 处理更复杂的复合表达：今年当前季度前一年 -> 当前年-1
        if (norm.contains("今年当前季度前一年") || norm.contains("本年当前季度前一年") ||
            norm.contains("今年当前季度前一年当前季度") || norm.contains("本年当前季度前一年当前季度")) {
            return getCurrentYear() - 1;
        }
        
        // 相对年份：本年、今年、本年度、当前年份、当前季度
        if (norm.contains("本年") || norm.contains("今年") || norm.contains("本年度") || norm.contains("当前年份") || norm.contains("当前季度")) {
            return getCurrentYear(); // 使用系统真实年份
        }
        // 上年/去年 -> 当前年-1
        if (norm.contains("上年") || norm.contains("去年")) {
            return getCurrentYear() - 1;
        }
        return currentYear; // 默认返回当前年份
    }

    private static int detectQuarter(String norm, int currentQuarter) {
        Matcher m;
        // 第X季度
        m = QUARTER_CN.matcher(norm);
        if (m.find()) {
            String qStr = m.group(1);
            return clampQuarter(parseQuarter(qStr));
        }
        // 第X季
        m = QUARTER_SEASON.matcher(norm);
        if (m.find()) {
            String qStr = m.group(1);
            return clampQuarter(parseQuarter(qStr));
        }
        // QX
        m = QUARTER_Q.matcher(norm);
        if (m.find()) {
            try {
                return clampQuarter(Integer.parseInt(m.group(1)));
            } catch (NumberFormatException ignored) {}
        }
        // 本季度/当前季度：使用系统当前季度
        m = CURRENT_QUARTER.matcher(norm);
        if (m.find()) {
            return getCurrentQuarter(); // 使用系统真实季度
        }
        return -1; // 未找到季度
    }

    private static int parseQuarter(String qStr) {
        if (qStr.length() == 1) {
            char c = qStr.charAt(0);
            if (CN_DIGIT.containsKey(c)) {
                return CN_DIGIT.get(c);
            }
        }
        try {
            return Integer.parseInt(qStr);
        } catch (NumberFormatException ignored) {}
        return -1;
    }

    private static int clampQuarter(int q) {
        return Math.max(1, Math.min(4, q));
    }

    private static int getCurrentYear() {
        return ZonedDateTime.now(ZoneId.of("Asia/Shanghai")).getYear();
    }

    private static int getCurrentQuarter() {
        int month = ZonedDateTime.now(ZoneId.of("Asia/Shanghai")).getMonthValue();
        return (month - 1) / 3 + 1;
    }

    /** 计算上一季度，必要时跨年。*/
    public static YearQuarter previousQuarter(int year, int quarter) {
        if (quarter > 1) {
            return new YearQuarter(year, quarter - 1, false);
        }
        return new YearQuarter(year - 1, 4, false);
    }

    @JsonIgnoreProperties(ignoreUnknown = true)
    public static class YearQuarter {
        private final int table_year;
        private final int task_quarter; // -1 表示未指定
        private final boolean aggregateYear; // true 表示本年合计（Q1..Q4）

        @JsonCreator
        public YearQuarter(@JsonProperty("table_year") int table_year, 
                          @JsonProperty("task_quarter") int task_quarter) {
            this(table_year, task_quarter, false);
        }

        public YearQuarter(int table_year, int task_quarter, boolean aggregateYear) {
            this.table_year = table_year;
            this.task_quarter = task_quarter;
            this.aggregateYear = aggregateYear;
        }

        @JsonProperty("table_year")
        public int getTableYear() { return table_year; }
        
        @JsonProperty("task_quarter")
        public int getTaskQuarter() { return task_quarter; }
        
        @JsonProperty("aggregateYear")
        public boolean isAggregateYear() { return aggregateYear; }

        @Override
        public String toString() {
            return "YearQuarter{" +
                    "table_year=" + table_year +
                    ", task_quarter=" + task_quarter +
                    ", aggregateYear=" + aggregateYear +
                    '}';
        }
    }
}


